package oop.lab.console.playground;

import java.util.List;
import java.util.Scanner;

import oop.lab.console.gameview.GameViewer;
import oop.lab.console.screen.RawScreen;
import oop.lab.console.screen.Screen;
import oop.lab.domain.board.PieceColor;
import oop.lab.domain.game.Game;
import oop.lab.domain.game.GameException;

/**
 * <pre>
  A B C D E F G H                                                 
1 · · · · · · · ·                           游戏列表:                 
2 · · · · · · · ·                           > 1.peace             
3 · · · · · · · ·   Player1 [Tom   ] ●        2.peace(结束状态测试)     
4 · · · · · · · ·   Player2 [Jerry ]          3.reversi           
5 · · · · · · · ·                             4.reversi(结束状态测试)   
6 · · · · · · · ·                             5.gomoku            
7 · · · · · · · ·                                                 
8 · · · · · · · ·                                                 
错误：未识别的或当前无效的命令:1z                                                
请玩家[Tom]输入落子位置(1A)/游戏编号:(1~5)/新游戏(peace/gomoku/reversi)/退出程序(quit)
 * </pre>
 * 
 * 游戏从左到右，从上到下依次为：
 * 1. 棋盘状态
 * 2. 玩家的状态（玩家列表、当前玩家等信息）
 * 3. 游戏列表（当前启动的游戏列表以及当前游戏）
 * 4. 游戏状态（错误信息、游戏当前状态信息等）
 * 5. 当前游戏支持的命令列表
 */
public class PlayGroundViewer {

    private final PlayGround playGround;

    public PlayGroundViewer(PlayGround playGround) {
        this.playGround = playGround;
    }

    // 显示游戏列表
    private void displayGameList(Screen screen) {
        int row = 0;
        screen.print(row++, 0, "游戏列表:");
        List<GameViewer> games = playGround.getGames();
        GameViewer currentGameViewer = playGround.getCurrentGameViewer(); // Get current viewer via PlayGround

        for (int i = 0; i < games.size(); i++) {
            GameViewer gameView = games.get(i);
            String gameDesc = gameView.getGameDesc();
            gameDesc = gameDesc.isEmpty() ? "" : "(" + gameDesc + ")";
            // Compare viewers directly for current game check
            if (gameView == currentGameViewer)
                screen.print(row++, 0, String.format("> %d.%s%s", i + 1, gameView.getGameType(), gameDesc));
            else
                screen.print(row++, 0, String.format("  %d.%s%s", i + 1, gameView.getGameType(), gameDesc));
        }
    }

    /*
     * 显示PlayGround中两个玩家状态
     */
    private void showPlayerStatus(Screen screen, GameViewer gameViewer) {
        Game game = gameViewer.getGame(); // Get game from the viewer
        Player player1 = playGround.getPlayer1();
        Player player2 = playGround.getPlayer2();

        String player1Status = gameViewer.getPlayerStatus(0, player1,
                game.getCurrentPlayer().equals(player1.getPieceColor()), game.isOver());
        String player2Status = gameViewer.getPlayerStatus(1, player2,
                game.getCurrentPlayer().equals(player2.getPieceColor()), game.isOver());

        screen.print(0, 0, player1Status);
        screen.print(1, 0, player2Status);
    }

    /**
     * 显示游戏的状态, 如当前玩家, 游戏是否结束等,如果游戏结束，显示游戏的结果
     */
    private void showGameStatus(Screen screen) {
        List<String> messages = new java.util.ArrayList<>();
        String lastErrorMessage = playGround.getLastErrorMessage(); // Get error from PlayGround
        if (lastErrorMessage != null)
            messages.add("错误：" + lastErrorMessage);

        String gameStatus = playGround.getCurrentGameViewer().getGameStatus(); // Get status from current viewer
        if (!gameStatus.isEmpty())
            messages.add(gameStatus);
        screen.print(0, 0, String.join(";", messages));
    }

    private void displayPlayground() { // No need to pass gameConsole, get it from playGround
        GameViewer gameViewer = playGround.getCurrentGameViewer();
        RawScreen screen = new RawScreen(50, 50);
        // 显示游戏。游戏的显示有下面五部分：
        // 1. 棋盘状态
        gameViewer.showBoard(screen.offset(0, 0));
        // 2. 玩家的状态（玩家列表、当前玩家等信息）
        this.showPlayerStatus(screen.offset(gameViewer.getSize().getY() / 2, gameViewer.getSize().getX() * 2 + 4),
                gameViewer);
        // 3. 游戏列表（当前启动的游戏列表以及当前游戏）
        this.displayGameList(screen.offset(1, gameViewer.getSize().getX() * 2 + 28));
        // 4. 游戏状态（错误信息、游戏当前状态信息等）
        this.showGameStatus(screen.offset(gameViewer.getSize().getY() + 1, 0));
        // 5. 当前游戏支持的命令列表
        gameViewer.showCommandList(screen.offset(gameViewer.getSize().getY() + 2, 0), playGround);
        screen.outputToConsole();
    }

    /**
     * 显示游戏主界面。
     */
    public void run() {
        try (Scanner scanner = new Scanner(System.in)) {
            while (true) {
                try {
                    // 显示游戏主界面
                    displayPlayground();

                    // 读入用户输入并执行命令
                    String input = scanner.next();
                    playGround.executeCommand(input); // Delegate command execution

                } catch (GameException e) {
                    // 只处理GameException
                    playGround.setLastErrorMessage(e.getMessage());
                }
            }
        }
    }

    public static void main(String[] args) {
        // Create Players
        Player player1 = new Player("Tom", PieceColor.BLACK);
        Player player2 = new Player("Jerry", PieceColor.WHITE);

        // Create PlayGround with players
        PlayGround playGround = new PlayGround(player1, player2);

        // Create PlayGroundVIew with the PlayGround logic instance
        PlayGroundViewer playGroundView = new PlayGroundViewer(playGround);

        // Run the view
        playGroundView.run();
    }
}
